﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Web.Configuration;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using System.Security.Principal;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.IO;
using System.Diagnostics;

namespace TFSBugTracking
{
    /// <summary>
    /// Class allowing to connect to Team Foundation Server Projects for WorkItem Access using tfs api.
    /// The class supports tfs impersotation (performing tfs actions on behalf of another tfs user)
    /// </summary>
    public class ImpersonatingTfsAdapter
    {
        private readonly TfsTeamProjectCollection _projectCollection;
        private readonly WorkItemStore _wiStore;
        private readonly ProjectBugMap[] _bugMaps;

        /// <summary>
        /// default ctor used to create a tfs connection
        /// </summary>
        /// <param name="tfsUrl">the url of the tfs</param>
        /// <param name="projectMappingsFile">the xml file where the project mappings are stored to</param>
        /// <param name="userMappingsFile">the xml file where the user  impersonation mappings are stored to</param>
        public ImpersonatingTfsAdapter(string tfsUrl, string projectMappingsFile, string userMappingsFile)
        {
            //set tfs client cache dir to temp (where network service account has write permission)
            if (WebConfigurationManager.AppSettings["WorkItemTrackingCacheRoot"] == null 
                || WebConfigurationManager.AppSettings["WorkItemTrackingCacheRoot"] == String.Empty)
            {
                string p =  System.IO.Path.GetTempPath() + "TFSClientCache";
                if ( !Directory.Exists(p))
                    Directory.CreateDirectory(p);
                WebConfigurationManager.AppSettings["WorkItemTrackingCacheRoot"] = p;
            } 

            //translate current user into tfs user
            var cred = new TfsCredentialTranslator(WindowsIdentity.GetCurrent(), userMappingsFile).ToTfs2010Credential(); 
            //setup tfs connect collection
            _projectCollection = new TfsTeamProjectCollection(new Uri(tfsUrl), cred);

            //impersonated tfs connect
            try
            {
                _projectCollection.Authenticate();
            }
            catch (Exception e)
            {   //trow connect exception and trace password for debugging purposes
                var ae = new ApplicationException(string.Format("unable to auth. {0} ", cred.UserName), e);
                Debug.WriteLine(ae);
                throw ae;
            }

            //get workitem service interface of tfs api
            _wiStore =_projectCollection.GetService<WorkItemStore>();
            //load project mappings file into memory
            _bugMaps = ProjectBugMap.GetMappings(projectMappingsFile);
        }
        
        
        /// <summary>
        /// String of the tfs user currently logged in for bug tracking
        /// </summary>
        public string ImpersonatedUser { get { return _projectCollection.AuthorizedIdentity.DisplayName; } }

        /// <summary>
        /// Mapping saetup for projects to file bug to
        /// </summary>
        public ProjectBugMap[] BugMaps
        {
            get { return _bugMaps; } 
        }

        /// <summary>
        /// WorkItem Store service from tfs
        /// </summary>
        public WorkItemStore WiStore
        {
            get { return _wiStore; }  
        }

        /// <summary>
        /// The original user logged in to web page
        /// </summary>
        public string CurrentUser { get { return WindowsIdentity.GetCurrent().Name; } }

        /// <summary>
        /// easy access method used to create a new bug item
        /// </summary>
        /// <param name="project">target project</param>
        /// <returns></returns>
        public WorkItem GetBugTemplate(string project)
        {
            var bugType = _wiStore.Projects[project].WorkItemTypes["Bug"];
            return  new WorkItem(bugType);
        }
    }

   
}
